package com.ruicar.afs.cloud.channel.channelworkflow.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruicar.afs.cloud.channel.cardealer.common.Constants;
import com.ruicar.afs.cloud.channel.cardealer.condition.DirectCarDealerCondition;
import com.ruicar.afs.cloud.channel.channelworkflow.condition.AccountToCaseCondition;
import com.ruicar.afs.cloud.channel.channelworkflow.condition.ChannelOnlineWorkFlowCondition;
import com.ruicar.afs.cloud.channel.channelworkflow.entity.WorkTaskAssign;
import com.ruicar.afs.cloud.channel.channelworkflow.entity.WorkTaskCreated;
import com.ruicar.afs.cloud.channel.channelworkflow.entity.WorkTaskDetail;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskApproveRecordService;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskAssignService;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskCreatedService;
import com.ruicar.afs.cloud.channel.channelworkflow.service.WorkTaskDetailService;
import com.ruicar.afs.cloud.channel.channelworkflow.vo.ChannelOnlineWorkTaskVo;
import com.ruicar.afs.cloud.channel.common.enums.ChannelAfsFlowEnum;
import com.ruicar.afs.cloud.channel.common.feign.ChannelUseCaseService;
import com.ruicar.afs.cloud.channel.common.until.ChannelConfig;
import com.ruicar.afs.cloud.channel.online.entity.ChannelBaseInfoTemp;
import com.ruicar.afs.cloud.channel.online.entity.ChannelReceivablesAccountTemp;
import com.ruicar.afs.cloud.channel.online.service.ChannelAccountInfoService;
import com.ruicar.afs.cloud.channel.online.service.ChannelOnlineService;
import com.ruicar.afs.cloud.channel.online.untils.ChannelOnlineConstants;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.uid.UidGenerator;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.WorkFlowResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.QueryFLowCmdRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.TaskSubmitRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.response.FlowCmdBean;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: sang jian
 * @date: 2020/7/21 15:45
 * @description:
 */

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/accountWorkFlow")
@Api(value = "accountWorkFlow", description = "收款账号审核")
public class ReceivablesAccountWorkflowController {

    private final WorkTaskAssignService workTaskAssignService;

    private final WorkTaskCreatedService workTaskCreatedService;
    private final WorkTaskDetailService workTaskDetailService;
    private final WorkTaskApproveRecordService workTaskApproveRecordService;
    private final WorkflowService workflowService;
    private ChannelConfig channelConfig;
    private ChannelUseCaseService channelUseCaseService;

    private ChannelAccountInfoService channelAccountInfoService;

    private ChannelOnlineService channelOnlineService;
    private final UidGenerator uidGenerator;


    /**
     * 收款账号提交工作流公用方法
     */
    @PostMapping(value = "/submitAccountToWorkflow")
    @ApiOperation(value = "收款账号维护提交工作流")
    public IResponse paymentAccountWorkflow(@RequestBody ChannelOnlineWorkFlowCondition condition) throws JsonProcessingException {
        Long channelId = condition.getChannelId();

        //查一下是否有草稿状态的账户信息
        List<ChannelReceivablesAccountTemp> accountTemps = channelAccountInfoService.list(Wrappers.<ChannelReceivablesAccountTemp>query().lambda()
                .eq(ChannelReceivablesAccountTemp::getChannelId, channelId)
                .eq(ChannelReceivablesAccountTemp::getStatus, Constants.DRAFT)
        );
        if(CollectionUtils.isEmpty(accountTemps)){
            //只更新开票信息
            ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getById(channelId);
            DirectCarDealerCondition directCarDealerCondition = new DirectCarDealerCondition();
            BeanUtils.copyProperties(baseInfoTemp,directCarDealerCondition);
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("clientId", channelConfig.getCaseClientId());
            headers.put("clientSecret", channelConfig.getCaseClientSecret());
            Assert.isTrue((boolean) channelUseCaseService.savaInvoiceInfo(directCarDealerCondition, headers).getData(),"操作失败,请重试!");
            return IResponse.success("操作成功");
        }
        //先查一下是否已经在流程
        List<WorkTaskDetail> workTaskDetails = workTaskDetailService.list(Wrappers.<WorkTaskDetail>query().lambda()
                .eq(WorkTaskDetail::getBusinessKey,channelId));
        if(workTaskDetails.size() > 0){
            for (WorkTaskDetail detail :workTaskDetails){
                String bizDataId = detail.getBizDataId();
                List<WorkTaskAssign> workTaskAssigns = workTaskAssignService.list(Wrappers.<WorkTaskAssign>query().lambda()
                        .eq(WorkTaskAssign::getBizDataId, bizDataId)
                        .eq(WorkTaskAssign::getAfsFlowKey,ChannelAfsFlowEnum.PAYMENT_ACCOUN)
                );
                if(workTaskAssigns.size() > 0){
                    return IResponse.fail("该合作商的收款账号审核已在流程中,请勿重复提交!");
                }
            }
        }
        //改收款账号状态
        //把这个合作商下的草稿状态的收款账号改成审核中
        for (ChannelReceivablesAccountTemp temp : accountTemps) {
            temp.setStatus(Constants.REVIEW);
            channelAccountInfoService.updateById(temp);
        }

        ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getById(channelId);

        StartFlowRequest startFlow = new StartFlowRequest();
        //枚举收款账号
        startFlow.setAfsFlowKey(AfsEnumUtil.key(ChannelAfsFlowEnum.PAYMENT_ACCOUN));
        startFlow.setBizDataId(uidGenerator.getUID() + "");
        //枚举收款账号
        startFlow.setFlowName((StringUtils.isEmpty(baseInfoTemp.getChannelFullName())?"":(baseInfoTemp.getChannelFullName())+"-")+AfsEnumUtil.desc(ChannelAfsFlowEnum.PAYMENT_ACCOUN));


        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(baseInfoTemp);
        JSONObject cancelJson = JSONObject.parseObject(json);
        workflowService.startWorkFlow(startFlow, cancelJson);

        //保存业务相关数据、用户前端逻辑判断
        WorkTaskDetail detail = new WorkTaskDetail();
        detail.setBizDataId(startFlow.getBizDataId());

        detail.setName(baseInfoTemp.getChannelFullName());
        detail.setFlowName(AfsEnumUtil.desc(ChannelAfsFlowEnum.PAYMENT_ACCOUN));
        //车商,渠道id绑定
        detail.setBusinessKey(channelId);
        workTaskDetailService.save(detail);
        workTaskApproveRecordService.startSave(AfsEnumUtil.desc(ChannelAfsFlowEnum.PAYMENT_ACCOUN), startFlow.getBizDataId());
        return IResponse.success("操作成功");

    }


    @PostMapping(value = "/getAccountWorkFlowDataByCondition")
    @ApiOperation(value = "多条件分页收款账户信息列表")
    public IResponse getByCondition(@RequestBody ChannelOnlineWorkFlowCondition condition) {
        Page page = new Page(condition.getPageNumber(), condition.getPageSize());
        //获取当前用户角色
        condition.setUserRoles(SecurityUtils.getRoles());
        IPage<List<ChannelOnlineWorkTaskVo>> accountInfoWorkflowInfoList = workTaskAssignService.getAccountInfoList(page, condition);
        return IResponse.success(accountInfoWorkflowInfoList);
    }


    @PostMapping(value = "/approveAccountWorkFlow")
    @ApiOperation(value = "提交收款账号审批流程")
    @SysLog("提交收款账号审批流程")
    @Transactional(rollbackFor = Exception.class)
    public IResponse approveAccountWorkFlow(@RequestBody ChannelOnlineWorkFlowCondition condition) throws JsonProcessingException {
        WorkTaskAssign assgin = workTaskAssignService.getOne(Wrappers.<WorkTaskAssign>query().lambda().eq(WorkTaskAssign::getBizDataId, condition.getBizDataId()));
        WorkTaskCreated created = workTaskCreatedService.getOne(Wrappers.<WorkTaskCreated>query().lambda().eq(WorkTaskCreated::getBizDataId, condition.getBizDataId()));
        WorkTaskDetail detail = workTaskDetailService.getOne(Wrappers.<WorkTaskDetail>query().lambda().eq(WorkTaskDetail::getBizDataId, condition.getBizDataId()));

        //提交完成之后删除其他人员代办
        List<WorkTaskAssign> assignList = workTaskAssignService.list(Wrappers.<WorkTaskAssign>query().lambda().eq(WorkTaskAssign::getBizDataId, condition.getBizDataId()));

        //关联合作商的id
        Long channelId = condition.getChannelId();
        ChannelBaseInfoTemp baseInfo = channelOnlineService.getById(channelId);
        //获取该合作商下所有审核中的收款账号
        List<ChannelReceivablesAccountTemp> inApproveAccountTempList = channelAccountInfoService.list(Wrappers.<ChannelReceivablesAccountTemp>query().lambda()
                .eq(ChannelReceivablesAccountTemp::getChannelId, channelId)
                .eq(ChannelReceivablesAccountTemp::getStatus, Constants.REVIEW)
        );

        //获取该合作商下的所有已启用收款账号信息
        List<ChannelReceivablesAccountTemp> enableAccountTempList = channelAccountInfoService.list(Wrappers.<ChannelReceivablesAccountTemp>query().lambda()
                .eq(ChannelReceivablesAccountTemp::getChannelId, condition.getChannelId())
                .eq(ChannelReceivablesAccountTemp::getStatus, Constants.ENABLED)
        );


        TaskSubmitRequest taskSubmitRequest = new TaskSubmitRequest();
        taskSubmitRequest.setGwtUserId(assgin.getAssignId());
        taskSubmitRequest.setAfsFlowKey(created.getAfsFlowKey());
        taskSubmitRequest.setBizDataId(created.getBizDataId());
        QueryFLowCmdRequest request = new QueryFLowCmdRequest();
        request.setFlowInstanceId(created.getFlowInstanceId());
        WorkFlowResponse<List<FlowCmdBean>> cmdResponse = workflowService.queryFlowCmd(request);
        List<FlowCmdBean> cmdList = cmdResponse.getAfsData();
        FlowCmdBean cmd = workTaskCreatedService.channelApprove(condition.getApprove(), cmdList);

        if (cmd != null) {
            log.info("==================================提交工作流开始==================================》");
            taskSubmitRequest.setCmdId(cmd.getId());
            ObjectMapper mapper = new ObjectMapper();
            //获取配置节点信息
            String json = mapper.writeValueAsString(baseInfo);
            JSONObject cancelJson = JSONObject.parseObject(json);
            workflowService.taskSubmit(taskSubmitRequest, cancelJson);

            condition.setTaskName(assgin.getTaskName());
            workTaskApproveRecordService.approveSave(condition, cmd);
            log.info("==================================业务逻辑处理开始==================================》");
            String taskMemo = created.getTaskMemo();

            if (!StrUtil.isBlank(taskMemo)) {
                JSONObject jsonMemo = (JSONObject) JSONObject.parse(taskMemo);
                String memo = (String) jsonMemo.get(AfsEnumUtil.key(ChannelAfsFlowEnum.NODE_LABEL));

                if (AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_BACK).equals(cmd.getCmdDis())) {
                    //首节点
                    if (ChannelOnlineConstants.FIRST_NODE.equals(memo)) {
                        //首节点(退回特殊处理逻辑)：退回
                        if (inApproveAccountTempList.size() > 0) {
                            for (ChannelReceivablesAccountTemp temp : inApproveAccountTempList) {
                                temp.setStatus(Constants.DRAWBACK);
                                channelAccountInfoService.updateById(temp);
                            }
                        }
                        workTaskDetailService.removeById(detail);
                        workTaskCreatedService.removeById(created);
                    }
                }
                if (AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_REFUSE).equals(cmd.getCmdDis())) {
                    //首节点//拒绝
                    if (inApproveAccountTempList.size() > 0) {
                        for (ChannelReceivablesAccountTemp temp : inApproveAccountTempList) {
                            temp.setStatus(Constants.REFUSE);
                            channelAccountInfoService.updateById(temp);
                        }
                    }
                }
                if (AfsEnumUtil.desc(ChannelAfsFlowEnum.CHANNEL_SUBMIT).equals(cmd.getCmdDis())) {
                    //审批通过

                    AccountToCaseCondition accountToCaseCondition = new AccountToCaseCondition();
                    //启用和审核中都有
                    if (enableAccountTempList.size() > 0 && inApproveAccountTempList.size() > 0) {
                        for (ChannelReceivablesAccountTemp temp1 : inApproveAccountTempList) {
                            for (ChannelReceivablesAccountTemp temp2 : enableAccountTempList) { //已启用的
                                if (temp1.getAccountAttribute().equals(temp2.getAccountAttribute()) && temp1.getCollectionType().equals(temp2.getCollectionType())) {
                                    //同类型的账号,把 审核中的状态设置成启用, 把已启用的状态设置成停用
                                    temp1.setStatus(Constants.ENABLED);
                                    temp2.setStatus(Constants.DISABLE);
                                    channelAccountInfoService.updateById(temp1);
                                    channelAccountInfoService.updateById(temp2);
                                } else {
                                    //没有同类型的账号,直接启用
                                    temp1.setStatus(Constants.ENABLED);
                                    channelAccountInfoService.updateById(temp1);
                                }
                            }
                        }
                    } else if (enableAccountTempList.size() == 0 && inApproveAccountTempList.size() > 0) {
                        //没有启用中的收款账号,直接启用审核中的账号即可
                        for (ChannelReceivablesAccountTemp temp1 : inApproveAccountTempList) {
                            temp1.setStatus(Constants.ENABLED);
                            channelAccountInfoService.updateById(temp1);
                        }
                    }
                    /***************同步账号信息到案件服务*************/
                    //查所有更新过的账号信息,然后同步案件

                    List<ChannelReceivablesAccountTemp> accountTempList1 = channelAccountInfoService.list(Wrappers.<ChannelReceivablesAccountTemp>query().lambda()
                            .eq(ChannelReceivablesAccountTemp::getChannelId, channelId)
                    );

                    ChannelBaseInfoTemp baseInfoTemp = channelOnlineService.getById(channelId);
                    accountToCaseCondition.setAccountTempList(accountTempList1);
                    accountToCaseCondition.setChannelBaseInfoTemp(baseInfoTemp);

                    Map<String, String> headers = new HashMap<String, String>();
                    headers.put("clientId", channelConfig.getCaseClientId());
                    headers.put("clientSecret", channelConfig.getCaseClientSecret());
                    Assert.isTrue((boolean) channelUseCaseService.saveAccountInfoToCase(accountToCaseCondition, headers).getData(),"操作失败,请重试!");
                }
            }
            //删除剩余节点数据信息
            for (int i = 0; i < assignList.size(); i++) {
                workTaskAssignService.removeById(assignList.get(i).getId());
            }
            return IResponse.success("提交成功");
        } else {
            return IResponse.fail("提交失败,提交指令异常，请确认！");
        }

    }


}
